// 使用jsdom在Node.js环境中渲染ECharts图表
const { JSDOM } = require('jsdom');
const echarts = require('echarts');

/**
 * 生成随机的饼图数据
 * @param {number} count - 数据项数量
 * @returns {Array} 饼图数据数组
 */
function generateRandomPieData(count = 6) {
  const categories = ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎', '社交推广', '线下活动', '其他渠道'];
  const colors = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4'];
  const data = [];
  
  // 随机选择不重复的分类
  const selectedCategories = [];
  while (selectedCategories.length < count && selectedCategories.length < categories.length) {
    const randomIndex = Math.floor(Math.random() * categories.length);
    if (!selectedCategories.includes(randomIndex)) {
      selectedCategories.push(randomIndex);
    }
  }
  
  // 生成总和为100的随机数据
  let total = 100;
  for (let i = 0; i < selectedCategories.length; i++) {
    const index = selectedCategories[i];
    let value;
    
    if (i === selectedCategories.length - 1) {
      // 最后一个数据项取剩余值
      value = total;
    } else {
      // 随机生成1到剩余值的2/3之间的值
      const maxValue = Math.floor(total * 2 / 3);
      value = Math.max(1, Math.floor(Math.random() * maxValue));
      total -= value;
    }
    
    data.push({
      name: categories[index],
      value: value,
      itemStyle: {
        color: colors[index]
      }
    });
  }
  
  return data;
}

/**
 * 创建ECharts饼图配置
 * @param {Array} data - 饼图数据
 * @returns {Object} ECharts配置对象
 */
function createPieChartOption(data) {
  return {
    title: {
      text: '访问来源分布',
      left: 'center',
      textStyle: {
        fontSize: 18,
        fontWeight: 'bold'
      }
    },
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
      orient: 'vertical',
      left: 'left',
      data: data.map(item => item.name)
    },
    series: [
      {
        name: '访问来源',
        type: 'pie',
        radius: '60%',
        center: ['50%', '60%'],
        data: data,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        },
        label: {
          show: true,
          formatter: '{b}: {d}%'
        },
        labelLine: {
          show: true
        }
      }
    ]
  };
}

/**
 * 使用jsdom和echarts在Node.js环境中生成真实的ECharts图表SVG
 * 然后将SVG转换为base64格式的图片数据
 * @param {Object} option - ECharts配置
 * @param {number} width - 图表宽度
 * @param {number} height - 图表高度
 * @returns {Promise<string>} base64编码的图片数据
 */
async function echartsToBase64(option, width = 800, height = 600) {
  try {
    console.log('正在处理ECharts配置...');
    console.log('- 图表类型:', option.series?.[0]?.type || '未指定');
    console.log('- 数据项数量:', option.series?.[0]?.data?.length || 0);
    console.log('- 图表尺寸:', `${width}x${height}`);
    
    // 使用jsdom创建虚拟DOM环境
    const { JSDOM } = require('jsdom');
    const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>');
    
    // 设置全局对象以支持ECharts
    global.window = dom.window;
    global.document = dom.window.document;
    global.navigator = dom.window.navigator;
    
    // 添加必要的方法以支持ECharts
    dom.window.requestAnimationFrame = (callback) => setTimeout(callback, 0);
    dom.window.cancelAnimationFrame = (id) => clearTimeout(id);
    
    // 创建一个简单的div作为图表容器
    const chartDiv = document.createElement('div');
    chartDiv.style.width = `${width}px`;
    chartDiv.style.height = `${height}px`;
    document.body.appendChild(chartDiv);
    
    // 为SVG渲染设置必要的mock方法
    global.SVGElement = class {}
    
    // 重新导入ECharts
    const echarts = require('echarts');
    
    // 创建ECharts实例，使用SVG渲染器
    const chart = echarts.init(chartDiv, null, {
      renderer: 'svg',  // 使用SVG渲染器避免canvas问题
      useDirtyRect: false,
      width: width,
      height: height
    });
    
    // 设置图表配置
    chart.setOption(option);
    
    // 获取SVG字符串
    const svgString = chart.getDom().querySelector('svg').outerHTML;
    
    // 将SVG转换为base64
    const svgBase64 = Buffer.from(svgString).toString('base64');
    const base64Data = `data:image/svg+xml;base64,${svgBase64}`;
    
    console.log('图表已成功渲染为SVG并转换为base64数据');
    return base64Data;
  } catch (error) {
    console.error('渲染图表时出错:', error);
    // 如果真实渲染失败，使用模拟数据作为降级方案
    console.log('降级到模拟数据方案...');
    
    // 生成一个基于配置的唯一标识
    const dataStr = JSON.stringify(option.series?.[0]?.data || []);
    const configHash = Buffer.from(dataStr).toString('base64').substring(0, 10);
    
    // 创建一个简单的SVG饼图来模拟真实图表
    const mockSvg = generateMockSvg(option, width, height, configHash);
    const mockBase64 = Buffer.from(mockSvg).toString('base64');
    
    return `data:image/svg+xml;base64,${mockBase64}`;
  }
}

/**
 * 生成模拟的SVG饼图
 * @param {Object} option - ECharts配置
 * @param {number} width - 宽度
 * @param {number} height - 高度
 * @param {string} configHash - 配置标识
 * @returns {string} SVG字符串
 */
function generateMockSvg(option, width, height, configHash) {
  const data = option.series?.[0]?.data || [];
  const total = data.reduce((sum, item) => sum + (item.value || 0), 0);
  
  let currentAngle = 0;
  const cx = width / 2;
  const cy = height / 2;
  const radius = Math.min(width, height) / 3;
  
  let paths = '';
  
  data.forEach((item, index) => {
    const value = item.value || 0;
    const percentage = value / total;
    const angle = percentage * 2 * Math.PI;
    
    const startX = cx + radius * Math.cos(currentAngle);
    const startY = cy + radius * Math.sin(currentAngle);
    
    currentAngle += angle;
    
    const endX = cx + radius * Math.cos(currentAngle);
    const endY = cy + radius * Math.sin(currentAngle);
    
    const largeArcFlag = angle > Math.PI ? 1 : 0;
    const color = item.itemStyle?.color || `hsl(${(index * 60) % 360}, 70%, 60%)`;
    
    paths += `<path d="M ${cx} ${cy} L ${startX} ${startY} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${endX} ${endY} Z" fill="${color}" stroke="white" stroke-width="2" />`;
  });
  
  return `
    <svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">
      <rect width="100%" height="100%" fill="white" />
      ${paths}
      <text x="${cx}" y="${cy}" text-anchor="middle" dominant-baseline="middle" font-family="Arial" font-size="16" fill="#333">ECharts Pie</text>
      <text x="${cx}" y="${cy + 20}" text-anchor="middle" dominant-baseline="middle" font-family="Arial" font-size="12" fill="#666">${configHash}</text>
    </svg>
  `.trim();
}

/**
 * 主函数：生成随机饼图并转为图片
 * @returns {Promise<string>} base64编码的图片src
 */
async function generatePieChartImage() {
  try {
    // 生成随机数据
    const pieData = generateRandomPieData();
    console.log('生成的随机数据:', pieData);
    
    // 创建图表配置
    const option = createPieChartOption(pieData);
    
    // 转换为base64图片
    const imageSrc = await echartsToBase64(option);
    console.log('图表已成功转换为图片');
    
    return imageSrc;
  } catch (error) {
    console.error('生成图表图片时出错:', error);
    throw error;
  }
}

// 示例使用
if (require.main === module) {
  generatePieChartImage()
    .then(imageSrc => {
      console.log('图片src:', imageSrc);
      // 在实际应用中，这里可以将imageSrc保存到文件或作为响应返回
    })
    .catch(error => {
      console.error('错误:', error);
    });
}

// 导出函数以便在其他模块中使用
module.exports = {
  generatePieChartImage,
  generateRandomPieData,
  createPieChartOption,
  echartsToBase64
};